package data.communication.lab1;

import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;

public class MultiThreadServer extends JFrame {
	// Text area for displaying contents

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JTextArea jta = new JTextArea();
	private String cwd = "/Applications/Android development/workspace/DataCommunicationLab1/res/CWD/";

	public static void main(String[] args) {
		new MultiThreadServer();
	}

	public MultiThreadServer() {
		// Place text area on the frame
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(new JScrollPane(jta), BorderLayout.CENTER);

		setTitle("MultiThreadServer");
		setSize(500, 300);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true); // It is necessary to show the frame here!

		try {
			// Create a server socket
			ServerSocket serverSocket = new ServerSocket(8000);
			jta.append("MultiThreadServer started at " + new Date() + '\n');

			// Number a client
			int clientNo = 1;

			while (true) {
				// Listen for a new connection request
				Socket socket = serverSocket.accept();

				// Display the client number
				jta.append("Starting thread for client " + clientNo + " at "
						+ new Date() + '\n');

				// Find the client's host name, and IP address
				InetAddress inetAddress = socket.getInetAddress();
				jta.append("Client " + clientNo + "'s host name is "
						+ inetAddress.getHostName() + "\n");
				jta.append("Client " + clientNo + "'s IP Address is "
						+ inetAddress.getHostAddress() + "\n");

				// Create a new thread for the connection
				HandleAClient thread = new HandleAClient(socket);

				// Start the new thread
				thread.start();

				// Increment clientNo
				clientNo++;
			}
		} catch (IOException ex) {
			System.err.println(ex);
		}
	}

	// Inner class
	// Define the thread class for handling new connection
	class HandleAClient extends Thread {

		private Socket socket; // A connected socket

		/**
		 * Construct a thread
		 */
		public HandleAClient(Socket socket) {
			this.socket = socket;
		}

		/**
		 * Run a thread
		 */
		public void run() {
			try {

				PrintStream outputToClient = new PrintStream(
						socket.getOutputStream());

				BufferedInputStream inputFromClient = new BufferedInputStream(
						socket.getInputStream());
				while (true) {
					byte[] buffer = new byte[1000];
					jta.append("stream ready\n");

					inputFromClient.read(buffer);

					String output = new String(buffer);
					jta.append("received: " + output + "\n");
					if (output.substring(0, 2).equals("ls")) {

						String c = "";
						String text = "";
						File f = new File(cwd);
						File[] listOfFiles = f.listFiles();
						if (listOfFiles != null) {
							for (int j = 0; j < listOfFiles.length; j++) {
								if (listOfFiles[j].isFile()) {
									text = listOfFiles[j].getName();
									c = text + " : " + c;
								}
							}
						} else {
							jta.append("No file(s) in directory sent\n");
							c = "no file(s) in the current working directory";
						}
						c += "\r\n";
						outputToClient.print(c);
						outputToClient.flush();

					} else if (output.substring(0, 3).equals("pwd")) {
						outputToClient.print(cwd + "\r\n");
						jta.append("Sent: " + cwd + "\n");
						outputToClient.flush();

					} else if (output.substring(0, 3).equals("get")) {
						jta.append("Creating file image...\n");

						File getFile = new File(cwd
								+ output.substring(4, output.length()));

						jta.append("Checking if file exists...\n");

						if (getFile.exists()) {

							jta.append("File exists. Creating input stream...\n");
							try (FileInputStream fileInput = new FileInputStream(
									getFile)) {
								jta.append("Creating buffer...\n");
								buffer = new byte[1000];
								System.out.println(buffer.length);

								BufferedInputStream bis = new BufferedInputStream(
										fileInput);

								OutputStream outputStream = socket
										.getOutputStream();

								jta.append("Sending number of bytes...\n");
								outputToClient.print(getFile.length() + "\r\n");

								jta.append("Transferring file...\n");

								while (bis.available() > 0) {

									outputStream.write(buffer, 0,
											bis.read(buffer));
								}
								outputStream.flush();
								fileInput.close();
								bis.close();
								jta.append("File transferred!\n");
							}
						} else {
							jta.append("File does not exist\n");
							outputToClient.print("0\r\n");
							outputToClient.flush();
						}
					} else {
						outputToClient.print("Error in command");
						jta.append("Sent: error command");
					}

					outputToClient.flush();
				}
			} catch (IOException e) {
				System.err.println(e);
			}
		}
	}
}